/*
 * Copyright (c) 1999-2003, Carnegie Mellon University. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 
 * 3. Products derived from the software may not be called "iVProg",
 *    nor may "iVProg" appear in their name, without prior written
 *    permission of Carnegie Mellon University.
 * 
 * 4. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes software developed by Carnegie Mellon University"
 */

package edu.cmu.cs.stage3.alice.core.util;

import edu.cmu.cs.stage3.alice.core.Element;
import edu.cmu.cs.stage3.alice.core.Property;
import edu.cmu.cs.stage3.alice.core.event.ChildrenListener;
import edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyListener;
import edu.cmu.cs.stage3.alice.core.event.PropertyListener;

public abstract class WorldListener {

 private edu.cmu.cs.stage3.alice.core.World m_world;
 private edu.cmu.cs.stage3.alice.core.event.ChildrenListener m_childrenListener = new edu.cmu.cs.stage3.alice.core.event.ChildrenListener() {
  public void childrenChanging( edu.cmu.cs.stage3.alice.core.event.ChildrenEvent e ) {
   WorldListener.this.handleChildrenChanging( e );
  }
  public void childrenChanged( edu.cmu.cs.stage3.alice.core.event.ChildrenEvent e ) {
   if( e.getChangeType() == edu.cmu.cs.stage3.alice.core.event.ChildrenEvent.CHILD_INSERTED ) {
    WorldListener.this.hookUp( e.getChild() );
   } else if( e.getChangeType() == edu.cmu.cs.stage3.alice.core.event.ChildrenEvent.CHILD_REMOVED ) {
    WorldListener.this.unhookUp( e.getChild() );
   }
   WorldListener.this.handleChildrenChanged( e );
  }
 };
 private edu.cmu.cs.stage3.alice.core.event.PropertyListener m_propertyListener = new edu.cmu.cs.stage3.alice.core.event.PropertyListener() {
  public void propertyChanging( edu.cmu.cs.stage3.alice.core.event.PropertyEvent e ) {
   WorldListener.this.handlePropertyChanging( e );
  }
  public void propertyChanged( edu.cmu.cs.stage3.alice.core.event.PropertyEvent e ) {
   WorldListener.this.handlePropertyChanged( e );
  }
 };
 private edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyListener m_objectArrayPropertyListener = new edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyListener() {
  public void objectArrayPropertyChanging( edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyEvent e ) {
   WorldListener.this.handleObjectArrayPropertyChanging( e );
  }
  public void objectArrayPropertyChanged( edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyEvent e ) {
   WorldListener.this.handleObjectArrayPropertyChanged( e );
  }
 };

 protected abstract void handleChildrenChanging( edu.cmu.cs.stage3.alice.core.event.ChildrenEvent e );
 protected abstract void handleChildrenChanged( edu.cmu.cs.stage3.alice.core.event.ChildrenEvent e );
 protected abstract void handlePropertyChanging( edu.cmu.cs.stage3.alice.core.event.PropertyEvent e );
 protected abstract void handlePropertyChanged( edu.cmu.cs.stage3.alice.core.event.PropertyEvent e );
 protected abstract void handleObjectArrayPropertyChanging( edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyEvent e );
 protected abstract void handleObjectArrayPropertyChanged( edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyEvent e );

 protected abstract boolean isPropertyListeningRequired( edu.cmu.cs.stage3.alice.core.Property property );
 protected abstract boolean isObjectArrayPropertyListeningRequired( edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty oap );

 public edu.cmu.cs.stage3.alice.core.World getWorld() {
  return m_world;
 }
 public void setWorld( edu.cmu.cs.stage3.alice.core.World world ) {
  if( m_world != world ) {
   if( m_world != null ) {
    unhookUp( m_world );
   }
   m_world = world;
   if( m_world != null ) {
    hookUp( m_world );
   }
  }
 }

 private boolean isChildrenListenerHookedUp( edu.cmu.cs.stage3.alice.core.Element element ) {
  edu.cmu.cs.stage3.alice.core.event.ChildrenListener[] childrenListeners = element.getChildrenListeners();
  //LOB for (ChildrenListener childrenListener : childrenListeners)
  int t_tam = childrenListeners!=null ? childrenListeners.length : 0;
  for (int i_i=0; i_i<t_tam; i_i++) {
   if( childrenListeners[i_i] == m_childrenListener ) { //L if( childrenListener == m_childrenListener )
    return true;
   }
  }
  return false;
 }
 private boolean isPropertyListenerHookedUp( edu.cmu.cs.stage3.alice.core.Property property ) {
  edu.cmu.cs.stage3.alice.core.event.PropertyListener[] propertyListeners = property.getPropertyListeners();
  //LOB for (PropertyListener propertyListener : propertyListeners)
  int t_tam = propertyListeners!=null ? propertyListeners.length : 0;
  for (int i_i=0; i_i<t_tam; i_i++) {
   if( propertyListeners[i_i] == m_propertyListener ) { //L if( propertyListener == m_propertyListener )
    return true;
   }
  }
  return false;
 }
 private boolean isObjectArrayPropertyListenerHookedUp( edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty oap ) {
  edu.cmu.cs.stage3.alice.core.event.ObjectArrayPropertyListener[] oapListeners = oap.getObjectArrayPropertyListeners();
  //LOB for (ObjectArrayPropertyListener oapListener : oapListeners)
  int t_tam = oapListeners!=null ? oapListeners.length : 0;
  for (int i_i=0; i_i<t_tam; i_i++) {
   if( oapListeners[i_i] == m_objectArrayPropertyListener ) { //L if( oapListener == m_objectArrayPropertyListener )
    return true;
   }
  }
  return false;
 }
 private void unhookUp( edu.cmu.cs.stage3.alice.core.Element element ) {
  if( isChildrenListenerHookedUp( element ) ) {
   element.removeChildrenListener( m_childrenListener );
   //System.err.println( "-" + element );
  }
  edu.cmu.cs.stage3.alice.core.Property[] properties = element.getProperties();
  //LOB for (Property propertyI : properties)
  int t_tam = properties!=null ? properties.length : 0;
  for (int i_i=0; i_i<t_tam; i_i++) {
   if( isPropertyListeningRequired( properties[i_i] ) ) { //L if( isPropertyListeningRequired( propertyI ) )
    if( isPropertyListenerHookedUp( properties[i_i] ) ) { //L if( isPropertyListenerHookedUp( propertyI ) )
     properties[i_i].removePropertyListener( m_propertyListener ); //L propertyI.removePropertyListener( m_propertyListener );
    }
   }
   if( properties[i_i] instanceof edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty ) { //L if( propertyI ...)
    edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty oapI = (edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty)properties[i_i]; //L (...)propertyI;
    if( isObjectArrayPropertyListeningRequired( oapI ) ) {
     if( isObjectArrayPropertyListenerHookedUp( oapI ) ) {
      oapI.removeObjectArrayPropertyListener( m_objectArrayPropertyListener );
     }
    }
   }
  } // for (int i_i=0; i_i<t_tam; i_i++)
  edu.cmu.cs.stage3.alice.core.Element[] children = element.getChildren();
  //LOB for (Element element2 : children)
  t_tam = children!=null ? children.length : 0;
  for (int i_i=0; i_i<t_tam; i_i++) {
   unhookUp( children[i_i] ); //L unhookUp( element2 );
  }
 }
 private void hookUp( edu.cmu.cs.stage3.alice.core.Element element ) {
  if( isChildrenListenerHookedUp( element ) ) {
   //pass
  } else {
   //System.err.println( "+" + element );
   element.addChildrenListener( m_childrenListener );
  }
  edu.cmu.cs.stage3.alice.core.Property[] properties = element.getProperties();
  //LOB for (Property propertyI : properties)
  int t_tam = properties!=null ? properties.length : 0;
  for (int i_i=0; i_i<t_tam; i_i++) {
   if( isPropertyListeningRequired( properties[i_i] ) ) { //L if( isPropertyListeningRequired( propertyI ) )
    if( isPropertyListenerHookedUp( properties[i_i] ) ) { //L if( isPropertyListenerHookedUp( propertyI ) )
     //pass
    } else {
     properties[i_i].addPropertyListener( m_propertyListener ); //L propertyI.addPropertyListener( m_propertyListener )
    }
   }
   if( properties[i_i] instanceof edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty ) { //L if( propertyI instanceof ...)
    edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty oapI = (edu.cmu.cs.stage3.alice.core.property.ObjectArrayProperty)properties[i_i]; //L (...)propertyI;
    if( isObjectArrayPropertyListeningRequired( oapI ) ) {
     if( isObjectArrayPropertyListenerHookedUp( oapI ) ) {
      //pass
     } else {
      oapI.addObjectArrayPropertyListener( m_objectArrayPropertyListener );
     }
    }
   }
  } // for (int i_i=0; i_i<t_tam; i_i++)
  edu.cmu.cs.stage3.alice.core.Element[] children = element.getChildren();
  //LOB for (Element element2 : children)
  t_tam = children!=null ? children.length : 0;
  for (int i_i=0; i_i<t_tam; i_i++) {
   hookUp( children[i_i] ); //L hookUp(element2);
  }
 }

}
